(function (line) {
    var expando = 'ln' + (-new Date),
        uid = 0,
        dataCache = {},
        getCache = function (obj, uid, name) {
            var objId = obj[uid] || {};
            if (typeof name == 'undefined') {
                return objId;
            }
            return objId[name] || {};
        },
        setCache = function (obj, uid, name, value) {
            obj[uid] = obj[uid] || {};
            obj[uid][name] = value;
        };
    line.extend(line, {
        data:function (obj, name, value) {
            var method = value ? line.setData : line.getData;
            return method(obj, name, value);
        },
        getGlobalCache:function () {
            return dataCache;
        },
        setData:function (obj, name, value) {
            if (obj.nodeType) {
                var id = obj[expando] = obj[expando] || ++uid;
                return setCache(dataCache, id, name, value);
            } else {
                return setCache(obj, expando, name, value);
            }
        },
        getData:function (obj, name) {
            if (obj.nodeType) {
                var id = obj[expando] = obj[expando] || ++uid;
                return getCache(dataCache, id, name);
            } else {
                return getCache(obj, expando, name);
            }
        },
        removeData:function (obj, name) {
            if (typeof name == 'undefined') {
                //delete all
                if (obj.nodeType) {
                    delete dataCache[obj[expando]];
                    obj.removeAttribute(expando);
                } else {
                    delete obj[expando];
                }
            } else {
                //delete by name
                if (obj.nodeType) {
                    delete dataCache[obj[expando]][name];
                } else {
                    delete obj[expando][name];
                }
            }
        }
    });
})(line);